/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pipeline;

import baseObjects.XML_Handler;
import corpus.Observable;
import corpus.Observer;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.Vector;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/**
 *
 * @author moshka
 */
public class TopBuffer implements Observable{


    Vector<Observer> observers = new Vector<Observer>();
    TopBufferElements elements = null;
    
    Logger topLogger = Logger.getLogger(this.getClass().getName());

    public TopBuffer() {
        FileHandler f;
        try {
            f = new FileHandler(this.getClass().getName(), 100 * 1024 * 1024, 1, true);
            topLogger.addHandler(f);
            topLogger.setLevel(Level.ALL);
            f.setFormatter(new SimpleFormatter());

           
        } catch (FileNotFoundException e){
        }catch (IOException e) {
        } catch (SecurityException e) {
        } catch (Exception e){
        } 


    }

    public TopBuffer(int topSize) {
        this();
        try{
             elements = (TopBufferElements)XML_Handler.readfileTop("backupTop.xml");
             System.out.println("TopBuffer generated from file, biggest: "+elements.getBiggsetScore());
        }catch(Exception e ){
            
        }finally{
            
            if (elements==null){
                elements = new TopBufferElements(topSize);
                System.out.println("topBuffer generated from null");
            }
        }
    }

    public synchronized double getBiggestScore() {
        return elements.getBiggsetScore();
    }

    public synchronized KeyboardCandidate[] getTop() {
        return elements.getTop();
    }

    public void stopAcctivity() {
        for (Handler h : topLogger.getHandlers()) {
            h.close();
        }
    }

    public synchronized void add(KeyboardCandidate key) {
        int boundery = (this.elements.getLocation() < this.elements.getTop().length ? this.elements.getLocation() : this.elements.getTop().length);
        KeyboardCandidate temp;
        int i, j;
        for (i = 0; i < boundery; i++) {
            if (key.getScore() < this.elements.getTop()[i].getScore()) {
                //put and push
                for (j = i; j < boundery; j++) {
                    temp = this.elements.getTop()[j];
                    this.elements.getTop()[j] = key;
                    key = temp;
                }

                if (boundery < this.getTop().length) {
                    this.getTop()[boundery] = key;
                    elements.addLocation();
                }
                topLogger.log(Level.ALL, printTop());
                updateAll(null);
                return;
            }
        }
        if (boundery < this.elements.getTop().length) {
            this.elements.getTop()[boundery] = key;
            elements.addLocation();
            topLogger.log(Level.ALL, printTop());
            updateAll(null);
            return;
        }
    }

    private String printTop() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < elements.getLocation(); i++) {
            KeyboardCandidate keyboardCandidate = this.getTop()[i];
            sb.append(NumberFormat.getNumberInstance().format(keyboardCandidate.getId()) + " :" + keyboardCandidate.getScore() + "\n " + printKeyBoard(keyboardCandidate) + "\n");
        }
        return sb.toString();
    }

    private String printKeyBoard(KeyboardCandidate k) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < k.getKeys().length; i++) {
            sb.append("||");
            for (int j = 0; j < k.getKeys()[i].length; j++) {
                sb.append(k.getKeys()[i][j].getRegular() + "||");
            }
            sb.append("\n");
        }
        return sb.toString();
    }

    public void addObserver(Observer o) {
        observers.add(o);
    }

    public void removeObserver(Observer o) {
        observers.removeElement(o);
    }

    public void updateAll(String s) {
         for (Observer observer : observers) {
            observer.recive(this, s);
        }
    }

    public void stopAndSave() {
        try {
            System.out.println(this.getClass().getName());
            XML_Handler.writeTopBackupPointToFile("backupTop.xml", this.elements);
        } catch (IOException ex) {
            
        }
    }

}
